/*
 * Copyright 2007 Peter Zelenay.
 * 
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 * 
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 * 
 * You should have received a copy of the GNU General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 *     
 */
package net.zelenay.jcrviewer.tree;

import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.io.IOException;

import javax.swing.BoxLayout;
import javax.swing.Icon;
import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JMenuItem;
import javax.swing.JPanel;
import javax.swing.JPopupMenu;
import javax.swing.JScrollPane;
import javax.swing.JTree;
import javax.swing.event.TreeSelectionEvent;
import javax.swing.event.TreeSelectionListener;
import javax.swing.tree.TreePath;

import org.springframework.core.io.Resource;

/**
 * 
 * @author Peter Zelenay
 * 
 */
public class TreePanel extends JPanel {

	/**
	 * 
	 */
	private static final long serialVersionUID = 1L;

	private JTree tree;

	private final JScrollPane scroller = new JScrollPane();

	private final JPanel toolBar = new JPanel();

	private final JButton refreshButton = new JButton();

	private final JPopupMenu popupMenu = new JPopupMenu("Items");

	private final Commands commandListener = new Commands();

	public TreePanel() {
		super();
		setLayout(new GridBagLayout());
		GridBagConstraints cs = new GridBagConstraints();
		cs.fill = GridBagConstraints.BOTH;
		cs.gridy = 1;
		cs.weightx = 1;
		cs.weighty = 1;
		add(scroller, cs);
	}

	public JTree getTree() {
		return tree;
	}

	public void setTree(JTree tree) {
		this.tree = tree;
		scroller.setViewportView(tree);
		initPopupMenu();
		initToolBar();
		GridBagConstraints cs = new GridBagConstraints();
		cs.fill = GridBagConstraints.BOTH;
		cs.gridy = 0;
		cs.gridx = 0;
		add(toolBar, cs);
	}

	public void setRefreshIcon(Resource refreshIcon) {
		try {
			Icon icon = new ImageIcon(refreshIcon.getURL());
			refreshButton.setIcon(icon);
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}

	}

	private void initToolBar() {
		toolBar.setLayout(new BoxLayout(toolBar, BoxLayout.X_AXIS));
		toolBar.add(refreshButton);
		refreshButton.setActionCommand(Commands.REFRESH);
		refreshButton.addActionListener(commandListener);

		getTree().addTreeSelectionListener(new TreeSelectionListener() {

			public void valueChanged(TreeSelectionEvent e) {
				commandListener.setActivePath(e.getPath());
			}
		});
	}

	private void initPopupMenu() {
		final JMenuItem colapseItem = new JMenuItem("Colapse");
		colapseItem.setActionCommand(Commands.COLAPSE);
		final JMenuItem expandItem = new JMenuItem("Expand");
		expandItem.setActionCommand(Commands.EXPAND);
		final JMenuItem refreshItem = new JMenuItem("Refresh");
		refreshItem.setActionCommand(Commands.REFRESH);

		popupMenu.add(expandItem);
		popupMenu.add(colapseItem);
		popupMenu.add(refreshItem);

		colapseItem.addActionListener(commandListener);
		expandItem.addActionListener(commandListener);
		refreshItem.addActionListener(commandListener);

		getTree().addMouseListener(new MouseAdapter() {

			@Override
			public void mouseReleased(MouseEvent e) {
				handleEvent(e);
			}

			@Override
			public void mousePressed(MouseEvent e) {
				handleEvent(e);
			}

			private void handleEvent(MouseEvent e) {
				if (e.isPopupTrigger()) {
					TreePath path = getTree().getClosestPathForLocation(
							e.getX(), e.getY());
					if (getTree().isExpanded(path)) {
						colapseItem.setEnabled(true);
						expandItem.setEnabled(false);
						refreshItem.setEnabled(true);
					} else {
						colapseItem.setEnabled(false);
						expandItem.setEnabled(true);
						refreshItem.setEnabled(false);
					}
					getTree().setSelectionPath(path);
					popupMenu.show(e.getComponent(), e.getX(), e.getY());
				}
			}

		});
	}

	private class Commands implements ActionListener {

		private static final String COLAPSE = "COLAPSE";

		private static final String EXPAND = "EXPAND";

		private static final String REFRESH = "REFRESH";

		private TreePath activePath;

		/**
		 * @return the activePath
		 */
		public TreePath getActivePath() {
			return activePath;
		}

		/**
		 * @param activePath
		 *            the activePath to set
		 */
		public void setActivePath(TreePath activePath) {
			this.activePath = activePath;
		}

		public void actionPerformed(ActionEvent e) {
			if (COLAPSE.equals(e.getActionCommand())) {
				getTree().collapsePath(getActivePath());
			} else if (EXPAND.equals(e.getActionCommand())) {
				getTree().expandPath(getActivePath());
			} else if (REFRESH.equals(e.getActionCommand())) {
				getTree().fireTreeExpanded(getActivePath());
			}
		}

	}
}
